package com.itheima.utils;

import org.springframework.cglib.beans.BeanCopier;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @ClassName: BeanUtils
 * @Description:
 * @author: Yrd
 * @date: 2021-11-03 10:59
 */
public class BeanUtils {

    //把JavaBean转化为map
    public static Map<String,Object> beanToMap(Object bean) throws Exception{
        Map<String,Object> map = new HashMap<>();
        //获取javaBean的描述器
        BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass(),Object.class);
        //获取属性描述器
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        //对属性迭代
        for (PropertyDescriptor pd : pds) {
            //属性名称
            String propertyName = pd.getName();
            //属性值，用getter方法获取
            Method getter = pd.getReadMethod();
            Object propertyValue = getter.invoke(bean);//用对象执行getter方法获得属性值

            //把属性名-属性值   村到Map中
            map.put(propertyName,propertyValue);
        }
        return map;
    }

    //把Map转化为JavaBean
    public static <T> T mapToBean(Map<String,Object> map,Class<T> clz) throws Exception{
        //创建一个需要转换为目标类型的类型的对象
        T obj = clz.newInstance();
        //从Map中获取和属性名称一样的值，把值设置给对象（setter方法）

        //获取javaBean的描述器
        BeanInfo beanInfo = Introspector.getBeanInfo(clz,Object.class);
        //得到属性的描述器
        PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
        //对属性进行迭代
        for (PropertyDescriptor pd : pds) {
            //得到属性的setter方法
            Method setter = pd.getWriteMethod();
            //得到key名字和属性名字相同的value设置给属性
            setter.invoke(obj,map.get(pd.getName()));
        }
        return obj;
    }

  




    public static void main(String[] args){
        User user = new User();
        user.setNameStr("xiaoli");
        user.setAgeStr("22");

        //try {
        //    Map<String, Object> userMap = beanToMap(user);
        //    System.out.println(userMap);
        //} catch (Exception e) {
        //    e.printStackTrace();
        //}
        //
        //System.out.println("========================================");
        //HashMap<String, Object> map = new HashMap<>();
        //map.put("nameStr","十一楼");
        //map.put("ageStr","99");
        ////map.put("address","福建");
        //try {
        //    User userBean = mapToBean(map, User.class);
        //    System.out.println(userBean);
        //} catch (Exception e) {
        //    e.printStackTrace();
        //}

        //Person person = new Person();
        //Student student = new Student();
        //student.setAge(12);
        //student.setNameStr("lidongxian");
        //student.setStudentCode("Y0001");
        //
        //System.out.println(person);
        //System.out.println(student);
        //System.out.println("==============");
        //copy(student,person);
        //System.out.println(person);
        //System.out.println(student);

        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
        map.put("xiao","8888");
        ConcurrentHashMap.KeySetView<String, String> strings = map.keySet();
        for (String string : strings) {
            System.out.println(string);
        }
        Collection<String> values = map.values();
        Set<Map.Entry<String, String>> entries = map.entrySet();

        //HashMap<String, String> hashMap = new HashMap<>();
        //Set<String> keySet = hashMap.keySet();
        //Collection<String> values = hashMap.values();
        //Set<Map.Entry<String, String>> entries = hashMap.entrySet();

    }


    private static final ConcurrentMap<String,BeanCopier> copiers = new ConcurrentHashMap<>();

    public static <T,V> void copy(T source,V target){
        if (null != source){
            BeanCopier cp = getBeanCopier(source.getClass(),target.getClass(),false);
            cp.copy(source,target,null);
        }
    }

    public static BeanCopier getBeanCopier(Class<?> sourceClass,Class<?> targetClass,boolean useConverter){
        String key = generateKey(sourceClass,targetClass);
        BeanCopier beanCopier = copiers.get(key);
        if(beanCopier == null){
            beanCopier = BeanCopier.create(sourceClass,targetClass,useConverter);
            copiers.put(key,beanCopier);
        }
        return beanCopier;
    }

    private static String generateKey(Class<?> srcClass,Class<?> destClass){
        StringBuilder sb = new StringBuilder("");
        String srcClassName = srcClass.getName();
        String destClassName = destClass.getName();
        sb.append(srcClassName).append("->").append(destClassName);
        return sb.toString();
    }



}






























